package com.zhou.framework.quartz.listener;

import com.zhou.framework.common.SpringFactory;
import com.zhou.framework.quartz.common.QuartzExecuteTypeEnum;
import com.zhou.framework.quartz.common.QuartzLogStatusEnum;
import com.zhou.framework.quartz.dao.QuartzLog;
import com.zhou.framework.quartz.service.QuartzLogService;
import com.zhou.framework.util.ExceptionUtil;
import lombok.extern.slf4j.Slf4j;
import org.quartz.*;
import org.quartz.impl.jdbcjobstore.Constants;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;

@Slf4j
public class MyTriggerListener implements TriggerListener,JobListener {
    private Map<String, QuartzLog> localLog = new HashMap<>(5);
    @Override
    public String getName() {
        return "zkTriggerListener";
    }

    @Override
    public void jobToBeExecuted(JobExecutionContext jobExecutionContext) {

    }

    @Override
    public void jobExecutionVetoed(JobExecutionContext jobExecutionContext) {

    }

    /**
     * (4)
     * job执行完毕
     */
    @Override
    public void jobWasExecuted(JobExecutionContext jobExecutionContext, JobExecutionException e) {
        //log.info("jobWasExecuted [" + key.getName() + "]");
        try{
            QuartzLog lo = localLog.get(Thread.currentThread().getName());
            if(lo != null){
                lo.setEndTime(new Date());
                if(e != null){
                    log.error("executed with error",e);
                    lo.setStatus(QuartzLogStatusEnum.ERROR.getEnumValue());
                    lo.setLog(ExceptionUtil.getString(e,lo.getName()+"执行失败，失败原因："));
                }else{
                    lo.setStatus(QuartzLogStatusEnum.DONE.getEnumValue());
                }
                SpringFactory.getBean(QuartzLogService.class).saveLog(lo);
            }
        }catch (Exception ex){
            log.error("jobWasExecuted出错",ex);
        }finally {
            localLog.remove(Thread.currentThread().getName());
        }
    }

    /**
     * (1)
     * Trigger被激发 它关联的job即将被运行
     */
    @Override
    public void triggerFired(Trigger trigger, JobExecutionContext context) {
        TriggerKey key = trigger.getKey();
        log.info("triggerFired [" + key.getName() + "]");
        try{
            QuartzLog log = new QuartzLog();
            log.setName(key.getName());
            log.setType(QuartzExecuteTypeEnum.AUTO.getEnumValue());
            log.setStartTime(context.getFireTime());
            //0-执行中 1-已完成
            log.setStatus(QuartzLogStatusEnum.DOING.getEnumValue());
            SpringFactory.getBean(QuartzLogService.class).saveLog(log);
            localLog.put(Thread.currentThread().getName(),log);
        }catch (Exception e){
            log.error("TriggerListener run error",e);
        }
    }

    /**
     * (2)
     * Trigger被激发 它关联的job即将被运行,先执行(1)，在执行(2) 如果返回TRUE 那么任务job会被终止
     */
    @Override
    public boolean vetoJobExecution(Trigger trigger, JobExecutionContext jobExecutionContext) {
        return false;
    }

    /**
     * (3)
     * 当Trigger错过被激发时执行,比如当前时间有很多触发器都需要执行，但是线程池中的有效线程都在工作，
     * 那么有的触发器就有可能超时，错过这一轮的触发
     */
    @Override
    public void triggerMisfired(Trigger trigger) {
        log.info("triggerMisfired [" + trigger.getKey().getName() + "]");
    }

    /**
     * (5)
     * 任务完成时触发
     */
    @Override
    public void triggerComplete(Trigger trigger, JobExecutionContext context, Trigger.CompletedExecutionInstruction completedExecutionInstruction) {
        try {
            TriggerKey key = trigger.getKey();
            log.info("triggerComplete ["+key.getName()+"]");
            Scheduler scheduler = context.getScheduler();
            if(scheduler != null) {
                Trigger.TriggerState state = scheduler.getTriggerState(key);
                if (state == Trigger.TriggerState.ERROR) {
                    log.info("triggerComplete ERROR:" + Constants.STATE_ERROR);
                }
            }
        } catch (Exception e) {
            log.error("获取定时任务执行状态错误", e);
        }
    }

}
